// ============================================================================
// Name : FieldInfo.java
// Author : iron.yin@gmail.com
// Version : v1.0
// Copyright : RisingSun CO,.LTD
// Description : FieldInfo.java in Java
// ============================================================================
package cc.risingsun.wing.core;

import java.util.Map;

import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

import cc.risingsun.wing.ds.DataStruct;

/**
 * 
 * @author iron.yin@gmail.com
 */
public class WingField extends WingBase{

	private final Type type;
	private final TypeInvoker invoker;
	//private final boolean isPrimitive;

	public WingField(String owner, String name, Type type) {
		super(owner,name);
		this.type = type;
		invoker = invokerMap.get(type.getSort());
	}

	public Type getType() {
		return type;
	}

	public void invoke(MethodVisitor mv) {
		invoker.apply(mv, this);
	}

	public String getOwnerDescribe() {
		return owner.getInternalName();
	}

	static final Map<Integer, TypeInvoker> invokerMap = DataStruct.hashMap();
	static {
		invokerMap.put(Type.INT, new TypeInvoker() {
			@Override
			public void apply(MethodVisitor mv, WingField fieldInfo) {
				mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object",
						"toString", "()Ljava/lang/String;");
				mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer",
						"parseInt", "(Ljava/lang/String;)I");
				mv.visitFieldInsn(PUTFIELD, fieldInfo.getOwnerDescribe(), fieldInfo
						.getName(), fieldInfo.getType().getDescriptor());
			}
		});

		invokerMap.put(Type.OBJECT, new TypeInvoker() {
			@Override
			public void apply(MethodVisitor mv, WingField fieldInfo) {
				mv.visitTypeInsn(CHECKCAST, fieldInfo.getType().getInternalName());
				mv.visitFieldInsn(PUTFIELD, fieldInfo.getOwnerDescribe(), fieldInfo
						.getName(), fieldInfo.getType().getDescriptor());
			}
		});
		invokerMap.put(Type.SHORT, new TypeInvoker() {
			@Override
			public void apply(MethodVisitor mv, WingField fieldInfo) {
				mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object",
						"toString", "()Ljava/lang/String;");
				mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer",
						"parseInt", "(Ljava/lang/String;)I");
				mv.visitFieldInsn(PUTFIELD, fieldInfo.getOwnerDescribe(), fieldInfo
						.getName(), fieldInfo.getType().getDescriptor());
			}
		});
	}

	interface TypeInvoker extends Opcodes {
		void apply(MethodVisitor mv, WingField fieldInfo);
	}
}
